Skip to content

Add support for Microsoft.WindowsAppSDK.Foundation bootstrapper#30

Open
mschofie wants to merge 1 commit intomainfrom
mschofie/bootstrap
Open

Add support for Microsoft.WindowsAppSDK.Foundation bootstrapper#30
mschofie wants to merge 1 commit intomainfrom
mschofie/bootstrap

Conversation

@mschofie
Copy link
Owner

@mschofie mschofie commented Mar 10, 2026

The Microsoft.WindowsAppSDK.Foundation NuGet package contains MSBuild/headers/source code/libs/dlls for 'bootstrapping' aspects of the Windows App SDK. This PR is to have a discussion as to how the support is surfaced.

A couple of points to discuss:

  1. There's a little awkwardness around Microsoft.WindowsAppSDK.Runtime. The Microsoft.WindowsAppSDK.Foundation NuGet doesn't depend on the Microsoft.WindowsAppSDK.Runtime NuGet, but the bootstrapper code needs the WindowsAppSDK-VersionInfo.h from the Microsoft.WindowsAppSDK.Runtime NuGet. As a result, the CMake logic here checks to see if the Microsoft.WindowsAppSDK.Runtime CMake package is available, and only if it is, creates the Microsoft.WindowsAppSDK.Foundation_FrameworkBootstrap target. I couldn't find analogous logic in the MSBuild scripts, so I'm not really sure how it's handled.

  2. This PR specifically adds support for the WindowsAppSdkBootstrapInitialize- and WindowsAppSdkDeploymentManagerInitialize- controlled bootstraps. In order to be able to accommodate multiple targets in a CMake build consuming Microsoft.WindowsAppSDK.Foundation_Framework with different configurations, I'm introducing generator-expression (documentation) logic to the Microsoft.WindowsAppSDK.Foundation_Framework target, so that consumers can set properties on the target that control the functionality that the consuming target gets. This is a little complicated to implement, but yields - IMHO - a well encapsulated implementation, and is clean to consume. Basically, each option that affects the source/pre-processor defines that a consume can apply manifests as a different target. Then the Microsoft.WindowsAppSDK.Foundation_Framework-target will depend on each of those targets only if the consuming target has properties set:

    • If the consuming target sets WindowsAppSdkBootstrapInitialize property (named identically to the MSBuild property), then the Microsoft.WindowsAppSDK.Foundation_Framework-target will add a dependency on the Microsoft.WindowsAppSDK.Foundation_DynamicDependencyBootstrap target.
    • If the consuming target sets the WindowsAppSdkDeploymentManagerInitialize property then the Microsoft.WindowsAppSDK.Foundation_Framework-target will add a dependency on the Microsoft.WindowsAppSDK.Foundation_DeploymentManagerBootstrap target.

    This means that consumers don't have to manage multiple libraries, CMake builds aren't bound to CMake variables (which would only be evaluated on the first find_package). The implementation - whilst a little verbose - is quite nicely encapsulated and 'correct'. Here's a diagram that attempts to explain the target-graph

---
config:
  flowchart:
    defaultRenderer: elk
---
graph TD
    Framework["Foundation_Framework"]
    Foundation["Foundation"]
    DynDepBoot["Foundation_DynamicDependencyBootstrap"]
    DeployBoot["Foundation_DeploymentManagerBootstrap"]
    Bootstrap["Foundation_Bootstrap"]
    Runtime["Microsoft.WindowsAppSDK.Runtime"]

    Framework --> Foundation
    Framework -.->|"WindowsAppSdkBootstrapInitialize"| DynDepBoot
    Framework -.->|"WindowsAppSdkDeploymentManagerInitialize"| DeployBoot
    DynDepBoot --> Bootstrap
    DeployBoot --> Bootstrap
    Bootstrap --> Runtime
Loading

Consumers would write code like:

# By linking to the '_Framework' variant of the Windows App SDK, the application will take a dependency on the Framework
# package for the Windows App SDK runtime.
#
target_link_libraries(Unpackaged_Console_Framework
    PRIVATE
        Microsoft.WindowsAppSDK.Foundation_Framework
        Microsoft.Windows.ImplementationLibrary
)

# Setting 'WindowsAppSdk*' target properties on _consumers_ of 'Microsoft.WindowsAppSDK.Foundation_Framework' controls
# the inclusion of the Windows App SDK Bootstrap infrastructure.
set_target_properties(Unpackaged_Console_Framework
    PROPERTIES
        # Controls whether the 'dynamic dependency' bootstrap will be added to the current target
        WindowsAppSdkBootstrapInitialize TRUE

        # Controls whether the 'deployment manager' bootstrap will be added to the current target
        WindowsAppSdkDeploymentManagerInitialize FALSE
)

I pushed a small self-contained buddy test here incase folks want to try things out. Note: this is based on the 'develop' branch, but this PR is for the 'main' branch.

I've validated with Ninja and Visual Studio 2022 generators. When both WindowsAppSdkBootstrapInitialize and WindowsAppSdkDeploymentManagerInitialize are unset or FALSE, the Microsoft.WindowsAppRuntime.Bootstrap.dll file isn't copied alongside the .exe. If either is TRUE, the file is copied, and the corresponding code is compiled into the consumer.

Copilot AI review requested due to automatic review settings March 10, 2026 00:38
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds CMake overlay support for the Microsoft.WindowsAppSDK.Foundation NuGet package’s “framework bootstrapper” scenario by introducing new convenience targets and conditionally exposing a bootstrap target when Microsoft.WindowsAppSDK.Runtime is available.

Changes:

  • Adds Microsoft.WindowsAppSDK.Foundation_Framework as an INTERFACE convenience target.
  • Conditionally defines Microsoft.WindowsAppSDK.Foundation_FrameworkBootstrap when Microsoft.WindowsAppSDK.Runtime can be found, wiring in bootstrapper sources/defines and linking to the bootstrap DLL/implib.
  • Leaves existing ..._SelfContained behavior intact.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link

@jonwis jonwis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems pretty reasonable. App "targets" the framework & bootstrapper. Is it an error to target _frameworkbootstrap without _framework ?

Copilot AI review requested due to automatic review settings March 10, 2026 16:36
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@mschofie
Copy link
Owner Author

mschofie commented Mar 10, 2026

Seems pretty reasonable. App "targets" the framework & bootstrapper. Is it an error to target _frameworkbootstrap without _framework ?

I think I have a proposal to comment (2) in the description that shakes out really quite nicely that means that _frameworkbootstrap would be an implementation detail. Let me write/code it up...


Ah. I should answer your question, though. I think it's fine to reference _frameworkbootstrap without _framework - you could be in a simple 'hosting exe' that doesn't need the winmd projections, but wants package-graph updates for DLL's that you LoadLibrary. But since the _framework target is really just setting include paths I don't think there's a concern to superset them.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 4 comments.

@mschofie mschofie force-pushed the mschofie/bootstrap branch from 71ecfbb to 32ecaa3 Compare March 10, 2026 23:54
Copilot AI review requested due to automatic review settings March 10, 2026 23:58
@mschofie mschofie force-pushed the mschofie/bootstrap branch from 32ecaa3 to 0fdee42 Compare March 10, 2026 23:58
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 3 comments.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants